package task

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/internal/pkg/code"
	"TaskAssignmentSystem/pkg/db/mysql"
	"TaskAssignmentSystem/pkg/oss"
	"TaskAssignmentSystem/pkg/timehandler"
	"TaskAssignmentSystem/pkg/utils"
	"fmt"
	"gorm.io/gorm"
	"time"
)

/*
 * 定时任务执行函数
 * 题目生效
 */

func TopicToTakeEffect(topicId []uint) {
	var topicDao dao.Common[dao.SystemTopic]
	topicDao.Tx = mysql.GetDB()
	topicDao.Query = map[string]interface{}{"id": topicId, "status": []int{0}} //支持未生效的
	topicDao.CustomWhere = append(topicDao.CustomWhere, fmt.Sprintf("end_date_time > '%s'", time.Now().In(utils.LocationZone).Format(timehandler.FormatLayoutTime)))
	topicDao.Update(map[string]interface{}{"receiver_id": "", "status": 5, "finish_time": nil, "priority": 1})
}

//题目失效

func TopicFailure(topicId []uint) {
	var topicDao dao.Common[dao.SystemTopic]
	topicDao.Query = map[string]interface{}{"id": topicId, "status": []int{0, 2, 3, 4, 5}} //已完成和已作废的 不做失效处理
	topicDao.Update(map[string]interface{}{"status": 7, "receiver_id": ""})
}

//题目作废

func TopicInvalid(topicId []uint) {
	txs := mysql.GetDB()
	//修改题目状态
	var topicDao dao.Common[dao.SystemTopic]
	topicDao.Query = map[string]interface{}{"id": topicId, "status": []int{0, 1, 2, 3, 4, 5}} //已作废和已失效的不做作废处理
	//res, _ := topicDao.SelectList()
	if err := topicDao.Update(map[string]interface{}{"receiver_id": "", "status": 6, "finish_time": nil}).Error; err != nil {
		fmt.Println(err)
	} else {
		//删除题目相关的答案
		if err := txs.Model(&dao.TopicAnswer{}).Where(map[string]interface{}{"system_topic_id": topicId}).Delete(&dao.TopicAnswer{}).Error; err != nil {
			fmt.Println(err)
		}
		//移除oss的答案
		res, _ := topicDao.FindAll(map[string]interface{}{})
		client := oss.BucketClient{}
		for _, u := range res {
			client.BatchRemoveFiles(fmt.Sprintf("task-assign/%s/%s", u.ProjectId, u.TopicId))
		}
	}
}

//返修

func TopicRepair(topicId []uint) {
	_db := mysql.GetDB()
	for _, t := range topicId {
		var topicDao dao.Common[dao.SystemTopic]
		topicDao.Tx = _db
		topicDao.Query = map[string]interface{}{"id": t, "status": 1} //该题目必须是已经完成的
		topic, err := topicDao.First(topicDao.Query)
		if err != nil {
			fmt.Println("error is %s", err)
		}
		//查询项目的答题时长
		var projectDao dao.Common[dao.SystemProject]

		project, err := projectDao.First(map[string]interface{}{"project_id": topic.ProjectId})
		if err != nil {
			fmt.Println("projectDao.First error is %s", err)
		}
		var finishDateTime time.Time
		location, _ := time.LoadLocation("Asia/Shanghai")
		if time.Now().Add(time.Duration(project.CountdownAnswer) * time.Second).In(location).After(topic.EndDateTime.In(location)) {
			finishDateTime = topic.EndDateTime
		} else {
			finishDateTime = time.Now().Add(time.Duration(project.CountdownAnswer) * time.Second).In(location)
		}
		topic.FinishTime = finishDateTime
		if err := topicDao.Update(map[string]interface{}{"status": 4, "finish_time": finishDateTime}).Error; err != nil {
			fmt.Println("topicDao.Update error is %s", err)
		}

		if err := RegressionQuestionClose(t, topic.EndDateTime); err != nil {
			fmt.Println("RegressionQuestionClose error is %s", err)
		}
	}

}

func RegressionQuestionClose(topicId uint, ExecutionDateTime time.Time) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		if ExecutionDateTime.After(time.Now().In(utils.LocationZone)) {
			//if ExecutionDateTime.Format(timehandler.FormatLayoutDate) == time.Now().In(utils.LocationZone).Format(timehandler.FormatLayoutDate) {
			//	//执行时间在当日，创建redis 过期事件
			//	expiration := ExecutionDateTime.Unix() - time.Now().In(utils.LocationZone).Unix()
			//
			//	key := utils.GenerateRedisKey(topicId, fmt.Sprintf("6"))
			//	value, _ := jsoniter.Marshal(map[string]interface{}{"task_type": 6, "status": 7})
			//	if setNX := redis.RedisGClient.SetNX(key, value, time.Duration(expiration)*time.Second).Err(); setNX != nil {
			//		return setNX
			//	}
			//} else {
			//创建一个倒计时任务
			var task dao.SystemTask
			task.TaskType = 6
			task.SystemTopicId = topicId
			task.ExecutionDateTime = ExecutionDateTime
			task.ExecutionData = map[string]interface{}{"task_type": 6, "status": 7}
			if err := tx.Model(&dao.SystemTask{}).Create(&task).Error; err != nil {
				return err
			}
			//}
		} else {
			var topicDao dao.Common[dao.SystemTopic]
			topicDao.Query = map[string]interface{}{"id": topicId, "status": []int{0, 2, 3, 4, 5}} //已完成和已作废的 不做失效处理
			if err := topicDao.Update(map[string]interface{}{"status": 7}).Error; err != nil {
				return err
			}
		}
		return nil
	})
}

//指派

type TaskAssignUser struct {
	TopicId       uint
	ExecutionData code.MapJSONB
}

func AssignUser(topicId []dao.SystemTask) {
	_db := mysql.GetDB()
	for _, u := range topicId {
		_db.Transaction(func(tx *gorm.DB) error {
			//var assign services.TopicService
			var topicDao dao.Common[dao.SystemTopic]
			topicDao.Tx = tx
			topicDao.Query = map[string]interface{}{"id": u.SystemTopicId, "status": []int{0, 1, 2, 3, 4, 5, 6}}
			var project dao.SystemProject
			systemTopic, err := topicDao.First(topicDao.Query)
			if err != nil {
				return err
			}
			tx.Model(&dao.SystemProject{}).Where("project_id = ?", u.ExecutionData["project_id"]).First(&project)

			//添加用户记录
			var topic_user_record dao.TopicUserRecord
			topic_user_record.TopicId = systemTopic.TopicId
			topic_user_record.UserId = fmt.Sprintf("%s", u.ExecutionData["user_id"])
			topic_user_record.ProjectId = systemTopic.ProjectId
			topic_user_record.SystemTopicId = systemTopic.Id
			topic_user_record.Tp = 1
			if err := tx.Model(&dao.TopicUserRecord{}).Create(&topic_user_record).Error; err != nil {
				return err
			}
			if err := topicDao.Update(map[string]interface{}{"receiver_id": u.ExecutionData["user_id"], "status": 3, "finish_time": u.ExecutionDateTime.Add(time.Second * time.Duration(project.CountdownAnswer))}).Error; err != nil {
				return err
			}
			return nil
		})
	}
}

func ToDoTask(topicIds []uint, taskType int) {
	switch taskType {
	case 5:
		TopicToTakeEffect(topicIds)
	case 6:
		TopicFailure(topicIds)
	case 2:
		TopicToTakeEffect(topicIds)
	case 4:
		TopicInvalid(topicIds)
	case 3:
		TopicRepair(topicIds)
	default:
		//ToDo
	}
}
